#include "chat_server.h"

#include <QDir>

const QString fileSavePath = "/home/xzz/chat_server_temp";
chat_server::chat_server(QWidget *parent)
    : QWidget(parent), server(new QTcpServer(this))
{
    createGroup();
    connect(server, &QTcpServer::newConnection, this,
            &chat_server::newConnection_slot);
}

chat_server::~chat_server()
{
}

void chat_server::createGroup()
{
    int port = 5001;
    bool result = server->listen(QHostAddress::Any, port);
    if (result)
        qDebug() << "建群成功";
    else
        qDebug() << "建群失败";
}

void chat_server::sendFileList(QTcpSocket *socket){
    QDir directory(fileSavePath);
    QStringList files = directory.entryList(QDir::Files);
    QString fileList = "FILE_LIST\n" + files.join("\n");

    QTextStream output(socket);
    output << fileList;
}

void chat_server::sendFile(QTcpSocket *socket, const QString &filename)
{
    QFile file(fileSavePath + "/" + filename);
    if (file.open(QIODevice::ReadOnly)) {
        QByteArray fileData = file.readAll();
        file.close();

        QString fileInfo = "FILEDATA\n" + filename + "\n" + QString::fromUtf8(fileData.toBase64());

        QTextStream output(socket);
        output << fileInfo;
    }
    if (!file.open(QIODevice::ReadOnly)) {
        qDebug() << "Failed to open file: " << file.errorString();
    }
}



void chat_server::newConnection_slot()
{
    socket = server->nextPendingConnection();
    QTextStream output(socket);

    if (sockets.size() == 5) {
        output << QString("人数上限，连接失败");
        socket->close();
        return;
    }
    sockets.append(socket);

    connect(socket, &QIODevice::readyRead, this, &chat_server::readyRead_slot);
    connect(socket, &QTcpSocket::disconnected, this,
            &chat_server::disconnected_slot);

    QString ip = socket->peerAddress().toString();
    quint16 port = socket->peerPort();
    QString portText = QString::number(port);
    QString text = "新用户连接";
    text.append(ip).append(":").append(portText);
    qDebug() << text;
}

void chat_server::disconnected_slot()
{
    // 拿到发射者
    socket = (QTcpSocket *)sender();

    for (int i = 0; i < sockets.size(); i++) {
        if (socket == sockets.at(i)) {
            qDebug() << "第" << i << "个客户端掉线了";
            // 获得对面的IP地址和端口号
            QString ip = sockets.at(i)->peerAddress().toString();
            quint16 port = sockets.at(i)->peerPort();
            QString portText = QString::number(port);
            QString text = "连接已断开！";
            text.append(ip).append(":").append(portText);
            qDebug() << text;
            sockets.removeAt(i);
        }
    }
}

void chat_server::readyRead_slot()
{
    QTcpSocket *socket = (QTcpSocket*)sender();
    QTextStream input(socket);
    QString request=input.readAll();
    if (request.startsWith("REQUEST_FILE_LIST")) {
        sendFileList(socket);
    }
    else if (request.startsWith("GETFILE")) {
        QString filename = request.mid(7);
        sendFile(socket, filename);}
        else
        {
        for (int i = 0; i < sockets.size(); i++) {
            if (sockets.at(i)->isReadable() &&
                sockets.at(i)->bytesAvailable() > 0) {
                qDebug() << "第" << i + 1 << "个客户发送的消息";
                QTextStream input(sockets.at(i));

                QString text = input.readAll();
                if (text.startsWith("INFO")) {
                    // 形成要发回给原客户端的处理后的 text1
                    QString text1 = text;
                    text1.append("---------------------------------我");

                    // 发回所有客户端
                    for (int j = 0; j < sockets.size(); j++) {
                        QTextStream output(sockets.at(j));
                        if (j == i) {
                            // 只有原客户端收到处理过的 text1
                            output << text1;
                            qDebug() << "已发回处理过的文本给第" << i + 1
                                     << "个客户端";
                        } else {
                            // 其他客户端收到原始的 text
                            output << text;
                            qDebug()
                                << "已发回原始文本给第" << j + 1 << "个客户端";
                        }
                    }
                }
            }
        }
        }
}
